package com.wj.init.controller;

import com.wj.init.entity.BaseEntity;
import com.wj.init.service.BaseService;
import com.wj.init.utils.Result;
import io.swagger.annotations.*;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ：吴健
 * @date ：2019-09-0420:55
 * @desc ：基础控制类常用方法
 */
abstract class BaseController<T extends BaseEntity> {

    /**
     * 获取数据service
     * @return repo
     */
    abstract BaseService<T> getService();


    /**
     * 检查参数是否异常
     *
     * @param params 参数
     * @return
     */
    boolean checkParams(Object... params) {
        for (Object param : params) {
            boolean paramNotEmpty = true;
            if (param == null) {
                paramNotEmpty = false;
            } else if (param instanceof CharSequence) {
                paramNotEmpty = ((CharSequence)param).length() != 0;
            } else if (param.getClass().isArray()) {
                paramNotEmpty = Array.getLength(param) != 0;
            } else if (param instanceof Collection) {
                paramNotEmpty = !((Collection)param).isEmpty();
            } else if (param instanceof  Map){
                paramNotEmpty = !((Map) param).isEmpty();
            }
            if (!paramNotEmpty) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取对应数据, 简单查询
     * @param page      分页, 页码
     * @param pageSize  分页, 每页数据量
     * @param order     排序字段
     * @param sort      正序 asc, 倒序 desc
     * @param model     查询条件
     * @return
     */
    @ApiOperation(value = "分页获取数据, 简单查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", dataType = "int", required = true, example = "0"),
            @ApiImplicitParam(name = "pageSize", value = "每页数据量", dataType = "int", required = true, example = "10"),
            @ApiImplicitParam(name = "order", value = "排序字段", dataType = "string"),
            @ApiImplicitParam(name = "sort", value = "正序/倒序?", dataType = "string")
    })
    @RequestMapping(value = "getData", method = RequestMethod.GET)
    String getData(@RequestParam(name = "page", defaultValue = "0") Integer page,
                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                   String order, String sort, T model) {
        Pageable pageable = checkParams(order)?
                PageRequest.of(page, pageSize, "desc".equalsIgnoreCase(sort)? Sort.by(order).descending() :
                        Sort.by(order).ascending()) : PageRequest.of(page, pageSize);
        return Result.success(getService().getList(pageable, model));
    }

    /**
     * 复杂查询
     * @param page      分页, 页码
     * @param pageSize  分页, 每页数据量
     * @param order     排序字段
     * @param sort      正序 asc, 倒序 desc
     * @param request   request
     * @return
     */
    @ApiOperation(value = "分页获取数据, 复杂查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", dataType = "int", required = true, example = "0"),
            @ApiImplicitParam(name = "pageSize", value = "每页数据量", dataType = "int", required = true, example = "10"),
            @ApiImplicitParam(name = "order", value = "排序字段", dataType = "string"),
            @ApiImplicitParam(name = "sort", value = "正序/倒序?", dataType = "string")
    })
    @RequestMapping(value = "getData2", method = RequestMethod.GET)
    String getData2(@RequestParam(name = "page", defaultValue = "0") Integer page,
                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                   String order, String sort, HttpServletRequest request) throws Exception {
        Pageable pageable = checkParams(order)?
                PageRequest.of(page, pageSize, "desc".equalsIgnoreCase(sort)? Sort.by(order).descending() :
                        Sort.by(order).ascending()) : PageRequest.of(page, pageSize);
        Map<String, String[]> map = new HashMap<>(request.getParameterMap());
        map.remove("page");
        map.remove("pageSize");
        map.remove("order");
        map.remove("sort");
        return Result.success(getService().getList(pageable, map));
    }

    /**
     * 保存一串数据
     * @param list list
     * @return
     */
    @ApiOperation(value = "批量保存")
    @RequestMapping(value = "saveList", method = RequestMethod.POST)
    String saveList(@RequestBody List<T> list) {
        if (!checkParams(list)) {
            return Result.PARAM_ERROR;
        }
        if (getService().save(list)) {
            return Result.SUCCESS;
        } else {
            return Result.ERROR;
        }
    }

    /**
     * 保存单个数据
     * @param model list
     * @return
     */
    @ApiOperation(value = "单个数据保存")
    @RequestMapping(value = "saveOne", method = RequestMethod.POST)
    String saveOne(@RequestBody T model) {
        if (!checkParams(model)) {
            return Result.PARAM_ERROR;
        }
        if (getService().save(model)) {
            return Result.SUCCESS;
        } else {
            return Result.ERROR;
        }
    }

    /**
     * 根据ID删除数据
     * @param id ID
     * @return
     */
    @ApiOperation(value = "根据ID删除数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键ID", required = true, dataTypeClass = String.class)
    })
    @RequestMapping(value = "delete", method = RequestMethod.DELETE)
    String delete(String id) {
        if (!checkParams(id)) {
            return Result.PARAM_ERROR;
        }
        getService().deleteById(id);
        return Result.SUCCESS;
    }
}
